package guutil

import (
	"fmt"
	"os"
	"runtime"
	"strings"
	"syscall"

	"gitee.com/MikeDDD/gu/logs"
)

/*
用法如下：

defer func() {
	if err := recover(); err != nil {
		util.LogRecoverError(err)
	}
}()
*/
func LogRecoverError(err any) {
	var sb strings.Builder
	sb.WriteString(fmt.Sprintf("PANIC:: %v\n", err))
	for i := 0; ; i++ {
		_, file, line, ok := runtime.Caller(i)
		if !ok {
			break
		}
		sb.WriteString(fmt.Sprintf("PANIC:: %v:%v\n", file, line))
	}
	logs.Error(sb.String())
}

/*
函数第一行

defer InDeferRecover()

主题代码
*/
func InDeferRecover() {
	if err := recover(); err != nil {
		LogRecoverError(err)
	}
}

func GoWithRecover(f func()) {
	go func() {
		defer InDeferRecover()

		f()
	}()
}

var mainSignal chan os.Signal

func SetMainSignal(c chan os.Signal) {
	mainSignal = c
}

func PanicSafe(msg string, params ...any) {
	logs.Error(msg, params...)

	mainSignal <- syscall.SIGILL
}
